package com.cloudbroker.openapi.manage.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.cloudbroker.bcs.common.configure.ConfigUtil;

public class HttpUtil {
    private static final Logger logger = Logger.getLogger(HttpUtil.class);
    private static final CloseableHttpClient httpClient;
    private static final RequestConfig requestConfig;
    public static final String CHARSET = "UTF-8";
    public static final int MAX_TOTAL_CONNECTIONS = 2000;//连接池最大并发连接数
    public static final int MAX_ROUTE_CONNECTIONS = 2000;//单路由最大并发数
    public static final int CONNECT_TIMEOUT = 6000;
    public static final int SOCKET_TIMEOUT = 6000;
    
    static {
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        cm.setDefaultMaxPerRoute(MAX_ROUTE_CONNECTIONS);
        httpClient = HttpClients.custom().setConnectionManager(cm).build();
        requestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT)
                .build();
    }
    
    public static String doGet(String url, Map<String, String> params) {
        return doGet(url, params, CHARSET);
    }
    
    public static String doPost(String url, Map<String, String> params) {
        return doPost(url, params, CHARSET);
    }
    
    /**
     * HTTP Get 获取内容
     *
     * @param url 请求的url地址 ?之前的地址
     * @param params 请求的参数
     * @param charset 编码格式
     * @return 页面内容
     */
    public static String doGet(String url, Map<String, String> params, String charset) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        HttpGet httpGet = null;
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
            }
            httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            if (null != httpGet) {
                httpGet.releaseConnection();
            }
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * HTTP Post 获取内容
     *
     * @param url 请求的url地址 ?之前的地址
     * @param params 请求的参数
     * @param charset 编码格式
     * @return 页面内容
     */
    public static String doPost(String url, Map<String, String> params, String charset) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        HttpPost httpPost = null;
        try {
            List<NameValuePair> pairs = null;
            if (params != null && !params.isEmpty()) {
                pairs = new ArrayList<NameValuePair>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
            }
            httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            if (pairs != null && pairs.size() > 0) {
                httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
            }
            long startTime = System.currentTimeMillis();
            CloseableHttpResponse response = httpClient.execute(httpPost);
            long endTime = System.currentTimeMillis();
            logger.error(url + " spend time " + (endTime - startTime) + " millis");
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (IOException e) {
            if (null != httpPost) {
                httpPost.releaseConnection();
            }
            e.printStackTrace();
        }
        return null;
    }
    
    public static void main(String[] args) {
        String getData = doGet("http://127.0.0.1/get.php/", null);
        System.out.println(getData);
        System.out.println("----------------------分割线-----------------------");
        String postData = doPost("http://127.0.0.1/get.php/", null);
        System.out.println(postData);
    }
    
    public static String doPostFunc(String functionId, Map<String, String> map) {
        String url = ConfigUtil.get("interface.uag.addr", "http://127.0.0.1:21100/hsbc_operate/");
        if (!url.endsWith("/")) {
            url = url + "/";
        }
        url += functionId;
        return doPost(url, map);
    }
    
}
